package com.ycxh.module.dbtoword.util;

import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.rtf.RtfWriter2;
import com.lowagie.text.rtf.style.RtfParagraphStyle;
import com.ycxh.module.dbtoword.domain.TableFileds;
import com.ycxh.module.dbtoword.domain.Tables;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

/**
 * 创建word文档
 * 利用IText导出Word https://www.manongdao.com/article-1909447.html
 *  https://github.com/flowstone/simon-itext-word/blob/master/src/main/java/me/xueyao/utils/WordUtils.java
 *  https://blog.csdn.net/weixin_35214204/article/details/114624499
 *  https://blog.csdn.net/weixin_42193405/article/details/97245828
 *  https://www.cnblogs.com/wmy10/p/15689485.html
 *
 * itext添加标题（heading）
 *  http://t.zoukankan.com/anrainie-p-2410013.html
 *  https://www.iteye.com/blog/sanry-1002091
 *
 *  https://github.com/DramaQueenGmbH/com.lowagie.itext/blob/master/core/com/lowagie/text/Table.java
 *
 * 步骤:
 *  1、建立文档
 *  2、创建一个书写器
 *  3、打开文档
 *  4、向文档中写入数据
 *  5、关闭文档
 */
@Service
public class TableToWordUtil {

    /**
     * 生成word文档
     *
     * @param tables：该数据库下所有表信息
     * @param filePath：生成文件保存地址
     * @param database：数据库名称
     * @param docFileName：生成数据库文档文件名
     * @param title:文件内容标题
     */
    public void toWord(JdbcMysql jdbcMysql, Connection conn, List<Tables> tables, String filePath, String database, String docFileName, String title) {
        if (jdbcMysql == null) {
            jdbcMysql = new JdbcMysql();
        }
        if (conn == null) {
            conn = jdbcMysql.getConn();
        }
        if (conn == null) {
            tables = new ArrayList();
        }
        // 设置纸张大小
        Document document = new Document(PageSize.A4);
        try {
            // 创建文件夹
            File dir = new File(filePath);
            if (!dir.exists()) {
                dir.mkdirs();
            }

            // 创建文件
            String docFilePath = filePath + File.separator + docFileName;
            File file = new File(docFilePath);
            if (file.exists() && file.isFile()) {
                file.delete();
            }
            file.createNewFile();

            // 写入文件信息
            // 建立一个书写器(Writer)与document对象关联，通过书写器(Writer)可以将文档写入到磁盘中
            RtfWriter2.getInstance(document, new FileOutputStream(docFilePath));
            document.open();

            // 头部标题
            // BOLDITALIC 粗斜体
            // Paragraph p = new Paragraph(title, new Font(Font.NORMAL, 24, Font.BOLDITALIC, new Color(0, 0, 0)));
            Paragraph p = new Paragraph(title, new Font(Font.NORMAL, 24, Font.BOLD, new Color(0, 0, 0)));
            p.setAlignment(1);
            document.add(p);

            // 设置中文字体
            // iText中输出中文，有三种方式：https://www.bbsmax.com/A/E35p2ANgzv/
            // 1、使用iTextAsian.jar中的字体
            // com.lowagie.text.DocumentException: Font 'STSongStd-Light' with 'UniGB-UCS2-H' is not recognized.
            // https://blog.csdn.net/weixin_42393758/article/details/90315753
            // BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            BaseFont bfChinese = BaseFont.createFont("Times-Roman", "winansi", BaseFont.NOT_EMBEDDED);
            // 正文字体风格
            Font contextFont = new Font(bfChinese, 10, Font.NORMAL);
            for (int i = 0; i < tables.size(); i++) {
                String table_name = tables.get(i).getName();
                String table_comment = tables.get(i).getComment();

                List<TableFileds> fileds = jdbcMysql.getTable(database, tables.get(i).getName(), conn);

                String all = "" + (i + 1) + " 表名称:" + table_name + (StringUtils.isBlank(table_comment) ? "" : ("（" + table_comment + "）"));

                // 添加段落
                document.add(new Paragraph(""));
                // 添加新页面
                // document.newPage();

                // 设置列数
                Table table = new Table(6);
                // 边框宽度
                table.setBorderWidth(1);
                // 单元格之间的间距
                table.setPadding(0);
                // 衬距
                table.setSpacing(0);
                // table.setConvert2pdfptable(true);
                // iText生成文字与表格之间的空行问题 https://ask.csdn.net/questions/60267
                table.setOffset(1f);

                // 添加表头的元素，并设置表头背景的颜色
                Color chade = new Color(176, 196, 222);

                Cell cell = new Cell("编号");
                addCell(table, cell, chade);
                cell = new Cell("字段名");
                addCell(table, cell, chade);
                cell = new Cell("类型");
                addCell(table, cell, chade);
                cell = new Cell("是否非空");
                addCell(table, cell, chade);
                cell = new Cell("是否主键");
                addCell(table, cell, chade);
                cell = new Cell("注释");
                addCell(table, cell, chade);

                // 为表格添加表头信息时，要注意的是一旦表头信息添加完了之后， 必须调用 endHeaders()方法，否则当表格跨页后，表头信息不会再显示
                table.endHeaders();

                // 表格的主体
                for (int k = 0; k < fileds.size(); k++) {
                    addContent(table, cell, (k + 1) + "");
                    addContent(table, cell, fileds.get(k).getField());
                    addContent(table, cell, fileds.get(k).getType());
                    addContent(table, cell, fileds.get(k).getNull().equals("YES") ? "否" : "是");
                    // key属性值 有些为MUL
                    // addContent(table, cell, fileds.get(k).getKey() != "" ? "是" : "否");
                    // MySQL Key值（PRI, UNI, MUL）的含义 https://blog.csdn.net/weixin_44026997/article/details/108725779
                    // PRI主键约束
                    // UNI唯一约束
                    // MUL可以重复。如果Key是MUL, 那么该列的值可以重复, 该列是一个非唯一索引的前导列(第一列)或者是一个唯一性索引的组成部分但是可以含有空值NULL
                    addContent(table, cell, fileds.get(k).getKey() != null && fileds.get(k).getKey().equalsIgnoreCase("pri") ? "是" : "否");
                    addContent(table, cell, fileds.get(k).getComment());
                }

                // Paragraph pheae = new Paragraph(all);
                // 一级标题方式1：一步到位
                // 为什么标题会占2行？？？
                // Paragraph pheae = new Paragraph(all, RtfParagraphStyle.STYLE_HEADING_1);

                // 一级标题方式2：先加再设置样式
                Paragraph pheae = new Paragraph(all);
                pheae.setFont(RtfParagraphStyle.STYLE_HEADING_1);
                // 设置下面空白宽度
                // pheae.setSpacingAfter(15f);

                // 写入表说明 标题
                document.add(pheae);

                // word建了标题之后按回车应该是正文的时候怎么按了回车还是标题
                // 添加空白行，抵消换行标题样式
                document.add(new Paragraph("", contextFont));

                // PdfPTable pdfPTable = table.createPdfPTable();
                // // 设置表格上面空白宽度
                // pdfPTable.setSpacingBefore(0);

                // 生成表格
                // document.add(pdfPTable);
                // 设置段落和表格之间的间距？
                document.add(table);

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (document != null) {
                document.close();
            }
            // 关闭连接
            jdbcMysql.closeAll(null, null, conn);
        }
    }

    /**
     * 添加表头到表格
     *
     * @param table
     * @param cell
     * @param chade
     */
    private void addCell(Table table, Cell cell, Color chade) {
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setBackgroundColor(chade);
        table.addCell(cell);
    }

    /**
     * 添加内容到表格
     *
     * @param table
     * @param content
     */
    private void addContent(Table table, Cell cell, String content) {
        cell = new Cell(content);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(cell);
    }

}
